﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PersonalWebsite.Core.Const;
using PersonalWebsite.Domain;
using PersonalWebsite.Domain.Abstract.DBContext;
using PersonalWebsite.Domain.Abstract.DBContext.Interceptors;
using PersonalWebsite.Domain.Abstract.UnitOfWork;
using PersonalWebsite.Infrastructure.DBContext;
using Volo.Abp.Modularity;

namespace PersonalWebsite.Infrastructure;

[DependsOn(typeof(DomainModule))]
public class InfrastructureModule: AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        AddDomainDBContext(context.Services, context.Services.GetConfiguration());
        RegisterRepositories(context.Services);
    }

    private void RegisterRepositories(IServiceCollection services)
    {
        var types = System.Reflection.Assembly.GetExecutingAssembly()
            .GetTypes().Where(c => isRepository(c) && !c.IsAbstract && !c.IsInterface);

        if (types != null && types.Any())
        {
            foreach (var type in types)
            {
                var iType = type.GetInterfaces().SingleOrDefault(c => isRepository(c));
                if (iType != null)
                    services.AddScoped(iType, type);
            }
        }

        bool isRepository(Type type)
        {
            return type.Name.EndsWith("Repository", StringComparison.CurrentCultureIgnoreCase);
        }
    }

    private void AddDomainDBContext(IServiceCollection services, IConfiguration configuration)
    {
        services.AddScoped<PublishDomainEventsInterceptor>();
        var dd = configuration.GetConnectionString(AppSettingsConst.ConnectionString.DEFAULT);
        services.AddDbContext<PersonalWebsiteDbContext>((serviceProvider, option) =>
        {
            string connectionString = configuration.GetConnectionString(AppSettingsConst.ConnectionString.DEFAULT);

            option.UseMySql(connectionString, ServerVersion.AutoDetect(connectionString))
            .AddInterceptors(serviceProvider.GetRequiredService<PublishDomainEventsInterceptor>());
        }, ServiceLifetime.Scoped)
        .AddScoped<DomainDBContext>(provider => provider.GetRequiredService<PersonalWebsiteDbContext>())
        .AddScoped<IUnitOfWork>(provider => provider.GetRequiredService<PersonalWebsiteDbContext>());
    }
}
